<!doctype html>
<html>
    <head>
        <title>HT for Web 批量手册</title>
        <meta charset="UTF-8">    
        <meta name="viewport" content="user-scalable=yes, width=1024">
        <style type="text/css"> 
            h1, h2, h3, h4, h5, h6, p, blockquote {
                margin: 0;
                padding: 0;
            }
            body {
                font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
                font-size: 13px;
                line-height: 18px;
                color: #737373;
                background-color: white; 
                margin: 10px 13px 10px 13px;
            }
            table {
                margin: 10px 0 15px 0;
                border-collapse: collapse;
            }
            td,th {	
                border: 1px solid #ddd;
                padding: 3px 10px;
            }
            th {
                padding: 5px 10px;	
            }
            a {
                color: #0069d6;
            }
            a:hover {
                color: #0050a3;
                text-decoration: none;
            }
            a img {
                border: none;
            }
            p {
                margin-bottom: 9px;
            }
            h1, h2, h3, h4, h5, h6 {
                color: #404040;
                line-height: 36px;
            }
            h1 {
                margin-bottom: 18px;
                font-size: 30px;
            }
            h2 {
                font-size: 24px;
            }
            h3 {
                font-size: 18px;
            }
            h4 {
                font-size: 16px;
            }
            h5 {
                font-size: 14px;
            }
            h6 {
                font-size: 13px;
            }
            hr {
                margin: 0 0 19px;
                border: 0;
                border-bottom: 1px solid #ccc;
            }
            blockquote {
                padding: 13px 13px 21px 15px;
                margin-bottom: 18px;
                font-family:georgia,serif;
                font-style: italic;
            }
            blockquote:before {
                content:"\201C";
                font-size:40px;
                margin-left:-10px;
                font-family:georgia,serif;
                color:#eee;
            }
            blockquote p {
                font-size: 14px;
                font-weight: 300;
                line-height: 18px;
                margin-bottom: 0;
                font-style: italic;
            }
            code, pre {
                font-family: Monaco, Andale Mono, Courier New, monospace;
            }
            code {
                background-color: #fee9cc;
                color: rgba(0, 0, 0, 0.75);
                padding: 1px 3px;
                font-size: 12px;
                -webkit-border-radius: 3px;
                -moz-border-radius: 3px;
                border-radius: 3px;
            }
            pre {
                display: block;
                padding: 14px;
                margin: 0 0 18px;
                line-height: 16px;
                font-size: 11px;
                border: 1px solid #d9d9d9;
                white-space: pre-wrap;
                word-wrap: break-word;
            }
            pre code {
                background-color: #fff;
                color:#737373;
                font-size: 11px;
                padding: 0;
            }
            sup {
                font-size: 0.83em;
                vertical-align: super;
                line-height: 0;
            }
            * {
                -webkit-print-color-adjust: exact;
            }
            @media screen and (min-width: 914px) {
                body {
                    width: 854px;
                    margin:10px auto;
                }
            }
            @media print {
                body,code,pre code,h1,h2,h3,h4,h5,h6 {
                    color: black;
                }
                table, pre {
                    page-break-inside: avoid;
                }
            }                        
            iframe{
                width: 100%;
                border: 1px solid #34495E;
                margin: 0;                
            }            
            .logo{
                vertical-align: middle;
            }

        </style>        
        <script>
            function init() {
                var logoSrc = '',
                    logos = document.querySelectorAll('.logo'),
                    i = 0;
                for (; i < logos.length; i++) {
                    logos[i].src = logoSrc;
                }
                
                var iframes = document.querySelectorAll('iframe'),
                    func = function(){};
                for (i=0; i < iframes.length; i++) {
                    var iframe = iframes[i];
                    
                    // a small hack to make it work on android
                    iframe.ontouchstart = func;
                    
                    var div = document.createElement('div');
                    div.innerHTML = '<a href="' + iframe.src + '" target="_blank">独立运行→</a>';
                    iframe.parentNode.insertBefore(div, iframe);
                }   
            }
        </script>    
    </head>
    <body onload="init();">
        <a href="http://www.hightopo.com"><img class="logo"></a>HT for Web 批量手册
        <hr style="margin: 1px 0 20px 0">
<p>索引</p>

<ul><li><a href="#ref_overview">概述</a></li><li><a href="#ref_databatch">图元批量</a><ul><li><a href="#ref_basic">基本属性</a></li><li><a href="#ref_texture">贴图属性</a>  </li><li><a href="#ref_other">其他属性</a>    </li><li><a href="#ref_transparent">透明属性</a> </li><li><a href="#ref_invalidate">无效批量</a></li><li><a href="#ref_line">线框批量</a></li><li><a href="#ref_switch">批量开关</a></li></ul></li></ul>

<hr/>

<div id="ref_overview"></div>

<h2>概述</h2>

<p><code>HT for Web</code>的树表格和拓扑图等<code>2D</code>组件，无需特殊处理即可轻松承载万以上<code>Data</code>元素，但对于<code>Graph3dView</code>组件如需承载上千上万的数量级，
则需要进行特殊的批量处理。批量能提高性能的原理在于，当图元一个个独立绘制模型时性能较差，而但一批图元聚合成一个大模型进行一次性的绘制时，
则会极大提高<code>WebGL</code>刷新性能。</p>

<p>批量的处理相当于吃饭，如果一小口一小口的吃速度慢得瓶颈在于交互过程过频繁，如果换个大一点的勺子大口吃就可以减少交互过程，
但<code>WebGL</code>、<code>JavaScript</code>和浏览器都是有内存等资源限制，<code>HT</code>自动把所有数据聚合成一个大批量只进行一次绘制也是不现实的，
相当于我们人的口再大也不可能一口吃下一碗饭，因此需要用户根据项目的具体情况，将图元归纳出不同的批量方案以提高绘制性能。</p>

<div id="ref_databatch"></div>

<h2>图元批量</h2>

<p>目前<code>HT</code>支持对图元的<code>body</code>部分进行批量，还不支持<code>label</code>、<code>note</code>和<code>icons</code>的附属部分的批量，因此本章节介绍的图元批量针对图元的主体模型部分。</p>

<div id="ref_basic"></div>

<h3>基本属性</h3>

<p><iframe src="examples/example_basic.html" style="height:350px"></iframe></p>

<pre><code>node.setStyle(&#39;batch&#39;, &#39;firstBatch&#39;);</code></pre>

<p>以上为最简单的批量设置方式，该方式下<code>batch</code>名相同的图元都会自动聚合成批量一次性绘制。通过切换上例工具条的<code>Enable Batch</code>开关可体验是否批量的性能差距。</p>

<pre><code>ht.Default.setBatchInfo(&#39;firstBatch&#39;, {
    color: &#39;red&#39;,
    brightness: true,
    blend: true
});    </code></pre>

<p>批量还有诸多参考可控制，大部分情况下需要先通过<code>ht.Default.setBatchInfo</code>函数全局注册批量，再对<code>Data</code>设置对应的<code>batch</code>批量名。
如果未通过<code>ht.Default.setBatchInfo</code>进行注册就设置图元的<code>batch</code>属性，则代表采用<code>HT</code>的默认批量参数：</p>

<ul><li><code>brightness</code>：默认为<code>false</code>，则图元选中的<code>select.brightness</code>效果不起作用，需要设置为<code>true</code>打开高亮功能</li><li><code>blend</code>：默认为<code>false</code>，代表图元不进行染色，需要设置为<code>true</code>打开染色功能</li><li><code>color</code>：默认为<code>undefined</code>，该属性优先级高于独立图元面颜色，因此如果设置了该颜色图元所有面都将显示为该颜色值</li></ul>

<p><code>Graph3dView</code>默认关闭了批量染色和批量亮度的功能，因此批量中如需启用<code>blend</code>和<code>brightness</code>，则需通过如下函数启用：</p>

<ul><li>启用批量染色：<code>graph3dView.setBatchBlendDisabled(false)</code></li><li>启用批量亮度：<code>graph3dView.setBatchBrightnessDisabled(false)</code></li></ul>

<div id="ref_texture"></div>

<h3>贴图属性</h3>

<p>批量解决了性能问题，但也带来了功能减少或减弱的副作用，例如目前<code>HT</code>一个批量仅支持一张贴图，该贴图信息由注册批量时的<code>image</code>属性决定，
这样对于六面体需要不同面贴不同的图片时，则需要将多张图片融合成一张大图片，然后由六面体独立定义每个面对应的<code>uv</code>相关参数实现。</p>

<p><iframe src="examples/example_uv.html" style="height:350px"></iframe></p>

<pre><code>for (var i = 0; i &lt; row; i++) {
    for (var j = 0; j &lt; column; j++) {
        createNode(startX + gap * j, startZ, size).s({
            &#39;batch&#39;: &#39;uvBatch&#39;,                            
            &#39;bottom.uv&#39;: [0.25, 0, 0.25, 0.25, 0.5, 0.25, 0.5, 0],
            &#39;left.uv&#39;: [0, 0.75, 0, 1, 0.25, 1, 0.25, 0.75],
            &#39;right.uv&#39;: [0.5, 0.75, 0.5, 1, 0.75, 1, 0.75, 0.75],                            
            &#39;all.blend&#39;: &#39;#00FFFF&#39;,
            &#39;top.visible&#39;: i % 2 === 0
        });
    }
    startZ -= gap;
}

ht.Default.setBatchInfo(&#39;uvBatch&#39;, {
    brightness: brightness,
    blend: blend,
    image: &#39;die&#39;,
    topUv: [0.25, 0.5, 0.25, 0.75, 0.5, 0.75, 0.5, 0.5],
    backUv: [0.25, 0.75, 0.25, 1, 0.5, 1, 0.5, 0.75],                    
    frontUv: [0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 0.25],
    reverseColor: &#39;yellow&#39;,
    reverseCull: reverseCull,
    reverseFlip: reverseFlip
});</code></pre>

<p>以上例子筛子的六个面的<code>uv</code>信息部分面通过注册<code>batchInfo</code>时全局设置，部分面通过图元的<code>style</code>对应的<code>*.uv</code>属性设置，
图元<code>style</code>配置的<code>uv</code>属性信息优先级高于注册批量参数，一般来说如果批量图元面的<code>uv</code>信息一致的情况下，通过全局配置较为方便，
不必更新每个图元对应面属性，如果有特殊图元不同于全局则可独立再设置<code>style</code>对应的<code>uv</code>信息。</p>

<p><code>uv</code>参数：</p>

<ul><li><code>leftUv</code>：默认为空，用于批量指定左面<code>uv</code>参数，优先级低于图元<code>Data</code>具体参数值<code>left.uv</code>和<code>all.uv</code></li><li><code>rightUv</code>：默认为空，用于批量指定右面<code>uv</code>参数，优先级低于图元<code>Data</code>具体参数值<code>rigth.uv</code>和<code>all.uv</code></li><li><code>frontUv</code>：默认为空，用于批量指定前面<code>uv</code>参数，优先级低于图元<code>Data</code>具体参数值<code>front.uv</code>和<code>all.uv</code></li><li><code>backUv</code>：默认为空，用于批量指定后面<code>uv</code>参数，优先级低于图元<code>Data</code>具体参数值<code>back.uv</code>和<code>all.uv</code></li><li><code>topUv</code>：默认为空，用于批量指定顶面<code>uv</code>参数，优先级低于图元<code>Data</code>具体参数值<code>top.uv</code>和<code>all.uv</code></li><li><code>bottomUv</code>：默认为空，用于批量指定底面<code>uv</code>参数，优先级低于图元<code>Data</code>具体参数值<code>bottom.uv</code>和<code>all.uv</code></li></ul>

<p><code>uvScale</code>参数：</p>

<ul><li><code>leftUvScale</code>：默认为空，用于批量指定左面<code>uvScale</code>参数，优先级低于图元<code>Data</code>具体参数值<code>left.uv.scale</code>和<code>all.uv.scale</code></li><li><code>rightUvScale</code>：默认为空，用于批量指定右面<code>uvScale</code>参数，优先级低于图元<code>Data</code>具体参数值<code>rigth.uv.scale</code>和<code>all.uv.scale</code></li><li><code>frontUvScale</code>：默认为空，用于批量指定前面<code>uvScale</code>参数，优先级低于图元<code>Data</code>具体参数值<code>front.uv.scale</code>和<code>all.uv.scale</code></li><li><code>backUvScale</code>：默认为空，用于批量指定后面<code>uvScale</code>参数，优先级低于图元<code>Data</code>具体参数值<code>back.uv.scale</code>和<code>all.uv.scale</code></li><li><code>topUvScale</code>：默认为空，用于批量指定顶面<code>uvScale</code>参数，优先级低于图元<code>Data</code>具体参数值<code>top.uv.scale</code>和<code>all.uv.scale</code></li><li><code>bottomUvScale</code>：默认为空，用于批量指定底面<code>uvScale</code>参数，优先级低于图元<code>Data</code>具体参数值<code>bottom.uv.scale</code>和<code>all.uv.scale</code></li><li><code>csgUvScale</code>：默认为空，用于批量指定<code>csg</code>面<code>uvScale</code>参数，优先级低于图元<code>Data</code>具体参数值<code>csg.uv.scale</code>和<code>all.uv.scale</code></li></ul>

<p><code>uvOffset</code>参数：</p>

<ul><li><code>leftUvOffset</code>：默认为空，用于批量指定左面<code>uvOffset</code>参数，优先级低于图元<code>Data</code>具体参数值<code>left.uv.offset</code>和<code>all.uv.offset</code></li><li><code>rightUvOffset</code>：默认为空，用于批量指定右面<code>uvOffset</code>参数，优先级低于图元<code>Data</code>具体参数值<code>rigth.uv.offset</code>和<code>all.uv.offset</code></li><li><code>frontUvOffset</code>：默认为空，用于批量指定前面<code>uvOffset</code>参数，优先级低于图元<code>Data</code>具体参数值<code>front.uv.offset</code>和<code>all.uv.offset</code></li><li><code>backUvOffset</code>：默认为空，用于批量指定后面<code>uvOffset</code>参数，优先级低于图元<code>Data</code>具体参数值<code>back.uv.offset</code>和<code>all.uv.offset</code></li><li><code>topUvOffset</code>：默认为空，用于批量指定顶面<code>uvOffset</code>参数，优先级低于图元<code>Data</code>具体参数值<code>top.uv.offset</code>和<code>all.uv.offset</code></li><li><code>bottomUvOffset</code>：默认为空，用于批量指定底面<code>uvOffset</code>参数，优先级低于图元<code>Data</code>具体参数值<code>bottom.uv.offset</code>和<code>all.uv.offset</code></li><li><code>csgUvOffset</code>：默认为空，用于批量指定<code>csg</code>面<code>uvOffset</code>参数，优先级低于图元<code>Data</code>具体参数值<code>csg.uv.offset</code>和<code>all.uv.offset</code></li></ul>

<blockquote><p>注意以上并没有<code>csgUv</code>参数，<code>csg</code>挖空的面的<code>uv</code>参数由具体<code>CSGNode</code>挖空图元各个面的<code>uv</code>参数决定，
但<code>csgUvScale</code>和<code>csgUvOffset</code>参数会影响所有<code>csg</code>挖空面的最终呈现效果。</p></blockquote>

<div id="ref_other"></div>

<h3>其他属性</h3>

<p><iframe src="examples/example_global.html" style="height:350px"></iframe></p>

<p>除了前面介绍的<code>color</code>、<code>brightness</code>和<code>blend</code>的批量参数外，还有以下批量参考可设置，这些参数都只能在全局注册批量时指定，
具体图元上的相应属性被忽略。</p>

<ul><li><code>image</code>：默认为空，指定则代表进行贴图显示，为空代表显示颜色  </li><li><code>light</code>：默认为<code>true</code>，代表显示光亮效果，可设置为<code>false</code>关闭光效果    </li><li><code>reverseCull</code>：默认为<code>false</code>，决定反面是否裁剪，可设置为<code>true</code>对反面进行裁剪不显示</li><li><code>reverseFlip</code>：默认为<code>false</code>，反面是否显示正面的内容，为<code>false</code>则显示<code>reverseColor</code>颜色</li><li><code>reverseColor</code>：默认为<code>#868686</code>，决定反面颜色</li><li><code>transparentMask</code>：默认值为<code>false</code>，该属性能使得图元不绘制显示在界面上，但依然可以点击选中</li><li><code>uvOffset</code>：默认值为空，该属性会在所有面已决定的<code>uv</code>参数上再增加偏移</li><li><code>uvScale</code>：默认值为空，该属性会在所有面已决定的<code>uv</code>参数上再乘以倍数</li><li><code>discardSelectable</code>：默认值为<code>true</code>，代表贴图透明度低到被剔除的部分也能点击选中，可设置为<code>false</code>则被剔除部分不可选中</li></ul>

<div id="ref_transparent"></div>

<h3>透明属性</h3>

<p>最后还有几个透明相关批量参数，目前同一批量仅支持都为不透明物体，或者都为透明物体，不支持部分面透明部分面不透明的混合情况。</p>

<ul><li><code>opacity</code>：默认值为<code>undefined</code>，整体图形在<code>3D</code>下的透明度，可值范围<code>0~1</code></li><li><code>transparent</code>：默认值为<code>false</code>，如果贴图有透明度，图形颜色有透明度，或者设置了<code>opacity</code>有透明度情况下，需要设置该参数为<code>true</code>   </li><li><code>autoSort</code>：默认值为<code>true</code>，透明物体需要以由远往近方式绘制才能在<a href="http://www.opengl.org/wiki/Transparency_Sorting">WebGL系统</a>
中正确呈现颜色叠加效果，<code>HT</code>内部默认会对批量透明进行排序后绘制，在某些情况下为提高性能可设置为<code>false</code>关闭自动排序功能</li></ul>

<p><iframe src="examples/example_transparent.html" style="height:350px"></iframe></p>

<p><iframe src="examples/example_wireframe.html" style="height:350px"></iframe></p>

<div id="ref_invalidate"></div>

<h3>无效批量</h3>

<p>批量除了有限功能限制的副作用外，对批量内的图元频繁更新也会导致性能不佳，一般建议将不常变化的图元归到同一批量中，
将常变化的图元归到同一批量中，如果需要对同批量中的大部分图元进行更新，建议可在更新前调用以下函数。
一般情况下注册到全局的批量参数较少需要修改，如果进行了修改也可以通过调用以下函数通知图形界面进行更新：</p>

<ul><li><code>g3d.invalidateBatch(name)</code>：无效指定的批量名对应的所有批量图元</li></ul>

<div id="ref_line"></div>

<h3>线框批量</h3>

<p><code>Graph3dView</code>中科呈现两类线框效果：</p>

<ul><li>通过<code>wf.*</code>的<code>style</code>类型参数控制呈现在六面体周围的线框，详见<a href="../..//core/3d/ht-3d-guide.html#ref_selection">3D手册</a></li><li><code>ht.Edge</code>和<code>ht.Polyline</code>呈现为线框效果，详见<a href="../../core/shape/ht-shape-guide.html#ref_polyline">形状手册</a>的空间管线章节</li></ul>

<p><code>Graph3dView</code>内部已自动对所有线框类型进行了批量，因此用户无需对线框设置批量。</p>

<div id="ref_switch"></div>

<h3>批量开关</h3>

<p><a href="#ref_basic">基本属性</a>中提到，<code>Graph3dView</code>默认关闭了批量染色和批量亮度的功能，批量中如需启用<code>blend</code>和<code>brightness</code>，
需通过<code>graph3dView.setBatchBlendDisabled(false)</code>和<code>graph3dView.setBatchBrightnessDisabled(false)</code>启用。</p>

<p><code>Graph3dView</code>上还有个<code>batchColorDisabled</code>的属性，该值默认为<code>false</code>也就是启用批量颜色，当系统场景无需批量，
也未使用到线框效果时，可通过<code>graph3dView.setBatchColorDisabled(true)</code>关闭批量颜色，这样有助于提高性能，
并留下更多资源允许加载更多盏<a href="../../core/lighting/ht-lighting-guide.html">灯光</a>效果。</p>    <hr id="contact" style="margin: 20px 0 1px 0">
    <a href="http://www.hightopo.com"><img class="logo"></a>欢迎交流 <a href="mailto:service@hightopo.com">service@hightopo.com</a>
</body>
</html>
